package com.example.demo1.pay.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.demo1.pay.entity.FundIntercourse;
import com.example.demo1.pay.entity.OrderPayLog;
import com.example.demo1.pay.entity.Wallet;
import com.example.demo1.pay.mapper.WalletMapper;
import com.example.demo1.pay.req.IDReq;
import com.example.demo1.pay.req.RefundReq;
import com.example.demo1.pay.service.FundIntercourseService;
import com.example.demo1.pay.service.OrderPayLogService;
import com.example.demo1.pay.service.WalletService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;


/**
 * <p>
 * 用户钱包 服务实现类
 * </p>
 *
 * @author gong
 * @since 2023-02-27
 */
@Service
public class WalletServiceImpl extends ServiceImpl<WalletMapper, Wallet> implements WalletService {

    @Resource
    WalletMapper walletMapper;

    @Resource
    OrderPayLogService orderPayLogService;

    @Resource
    FundIntercourseService fundIntercourseService;

    /**
     *  1.查询用户钱包余额
     */
    @Override
    public List<Wallet> getFund(Long userId) {
        return this.baseMapper.selectList(new QueryWrapper<Wallet>().eq("user_id", userId));
    }

    /**
     *  2.用户消费100元的接口
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean pay(IDReq req) throws Exception {
        //付款方钱包id
        String payerWalletId = req.getPayerWalletId();
        //收款方钱包id
        String payeeWalletId = req.getPayeeWalletId();
        //设置支付金额为100
        BigDecimal money = req.getMoney();

        //更新付款方钱包表资金 -100
        int count = walletMapper.payment(req.getMoney(), Long.valueOf(payerWalletId));
        if (count < 1) {
            throw new Exception("钱包可用资金不足");
        }
        //更新收款方钱包表资金 +100
        int payeeCount = walletMapper.updateWalletAddAmountById(req.getMoney(), Long.valueOf(payeeWalletId));
        if (payeeCount < 1) {
            throw new Exception("收款方账号异常");
        }
        //更新订单表
        int addOrderPayLog = orderPayLogService.addOrderPayLog("112233", payerWalletId,
                payeeWalletId, money, "ok");
        if (addOrderPayLog < 1){
            throw new Exception("订单表数据插入异常");
        }
        //更新资金流水表
        fundIntercourseService.setFundIntercourse(payerWalletId, payeeWalletId, money, "out",
                "300_payment", "112233");
        fundIntercourseService.setFundIntercourse(payerWalletId, payeeWalletId, money, "in",
                "400_receipt", "112233");
        return true;
    }

    /**
     *  3.用户退款20元接口
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean refund(RefundReq req) throws Exception {
        //获取要退款的订单号
        String serialNumber = req.getSerialNumber();
        //要退款的金额
        BigDecimal money = req.getMoney();
        List<OrderPayLog> orderPayLogs = orderPayLogService.list(new QueryWrapper<OrderPayLog>().
                eq("serial_number", serialNumber));
        if (orderPayLogs == null || orderPayLogs.size() <1) {
            throw new Exception("要退款的订单不存在");
        }
        OrderPayLog orderPayLog = orderPayLogs.get(0);
        String payerFundAccount = orderPayLog.getPayerFundAccount();
        String payeeFundAccount = orderPayLog.getPayeeFundAccount();
        //更新订单表
        int orderCount = orderPayLogService.refundSerialNumber(serialNumber, money);
        if (orderCount < 1){
            throw new Exception("退款失败");
        }

        //更新资金流水表
        fundIntercourseService.setFundIntercourse(payerFundAccount, payeeFundAccount, money,
                "out", "500_withdrawal:退款", "112233");
        fundIntercourseService.setFundIntercourse(payerFundAccount, payeeFundAccount, money,
                "in", "500_withdrawal:退款", "112233");
        return true;
    }


    /**
     * 4.查询用户钱包金额变动明细的接口
     */
    @Override
    public List<FundIntercourse> getFundIntercourse(String payerWalletId) {
        return fundIntercourseService.list(new QueryWrapper<FundIntercourse>().
                eq("wallet_id", payerWalletId).eq("status", "ok"));
    }
}
